#include "PrecompiledHeader_Reborn.h"
#include "StarSystem.h"

/*--------------------------------------------------------------------------*/

StarSystem::StarSystem(NodeCreation& nc) :
	ICelestial(nc, ECelestialType::Starsystem)
{
	this->m_isCamInside = false;
}

/*--------------------------------------------------------------------------*/

StarSystem::~StarSystem()
{

}

/*--------------------------------------------------------------------------*/

void StarSystem::GenerateContent()
{
	srand(this->m_starid);
	float maxdistance = 300000.0f;

	this->m_planets = RandInt(2, 10);

	NodeCreation nc;
	nc.m_flags = 0;
	nc.m_parent = this;
	nc.m_scene = this->GetSceneInstance();

	CelestialStar* star = new CelestialStar(nc);
	this->m_ownedCelestials.push_back(star);
	float sunRadius = ::RandFloat(0.5f, 3.0f) * KM(700000.0f);
	star->SetScale(sunRadius);
	star->SetName("CelestialStar::Star");
	float sunOrbit = ::RandFloat(2.0f, 5.0f) * sunRadius;

	this->m_sunlight = new PointLight(nc);
	this->m_sunlight->SetName("PointLight::StarLight");
	this->m_sunlight->SetDiffuse(this->m_desc.m_color);
	this->m_sunlight->SetAmbient(this->m_desc.m_color);
	this->m_sunlight->SetDiffuse(Color::White);
	this->m_sunlight->SetAmbient(Color::White);
//
// 	CelestialPlanet* planet = new CelestialPlanet(nc);
// 	//this->m_ownedCelestials.push_back(planet);
// 	float planetRadius = 9000.0f;//::RandFloat(0.3f, 3.0f) * KM(10000.0f);
// 	planet->SetOrbit(0.0f);
//
// 	this->SetRadius(50000.0f);

	for (uint i = 0; i < this->m_planets; ++i)
	{
		nc.m_parent = star;
		CelestialPlanet* planet = new CelestialPlanet(nc);
		this->m_ownedCelestials.push_back(planet);
		float planetRadius = ::RandFloat(0.3f, 3.0f) * KM(10000.0f);
		planet->SetOrbit(sunOrbit);
		planet->SetYearLength(::RandFloat(10.0f, 30.0f));

		std::stringstream ss;
		ss << "CelestialPlanet::Planet#" << i << " (" << this->m_planets << ")";
		planet->SetName(ss.str());

		float planetOrbit = ::RandFloat(4.0f, 10.0f) * planetRadius;
		float maxPlanetRadius = planetRadius;

		uint moons = ::RandInt(0, 7);

		for (uint j = 0; j < 0/*moons*/; ++j)
		{
			nc.m_parent = planet;
			CelestialPlanet* moon = new CelestialPlanet(nc);
			this->m_ownedCelestials.push_back(moon);
			float moonRadius = ::RandFloat(0.1f, 0.7f) * planetRadius;
			moon->SetOrbit(planetOrbit);
			moon->SetYearLength(::RandFloat(10.0f, 30.0f));
			moon->SetRadius(moonRadius);

			std::stringstream ss;
			ss << "CelestialPlanet::Moon#" << j << " (" << moons << ") of Planet#" << i << " (" << this->m_planets << ")";
			moon->SetName(ss.str());

			maxPlanetRadius = std::max(planetRadius, planetOrbit + moonRadius);
			planetOrbit *= ::RandFloat(1.5f, 2.5f);
		}

		maxdistance = std::max(maxdistance, maxPlanetRadius + sunOrbit);

		planet->SetRadius(maxPlanetRadius);
		sunOrbit *= ::RandFloat(1.5f, 2.5f);
	}

	star->SetRadius(maxdistance * 2.0f);
	this->m_sunlight->SetRadius(maxdistance);

	this->SetRadius(maxdistance * 2.0f);
}

/*--------------------------------------------------------------------------*/

void StarSystem::DestroyContent()
{

}

/*--------------------------------------------------------------------------*/

void StarSystem::RenderableBinder(uint treeCalcFlags)
{

}

/*--------------------------------------------------------------------------*/

void StarSystem::RenderableHelper(const uint i, ERenderQuality::Type quality, uint pendingInstances)
{

}

/*--------------------------------------------------------------------------*/

void StarSystem::OnTreeGoToUp(uint arg)
{
	//g_Explorer->LeaveStarSyste2m(this->m_starid, this->GetSceneInstance()->GetCamera(arg)->GetPosition());
}

/*--------------------------------------------------------------------------*/

uint StarSystem::GetStarId()
{
	return this->m_starid;
}

/*--------------------------------------------------------------------------*/

void StarSystem::CalculateChildsMovement()
{
	for (auto iter = this->m_ownedCelestials.begin(); iter != this->m_ownedCelestials.end(); ++iter)
	{
		(*iter)->DoMovement();
	}
}

/*--------------------------------------------------------------------------*/

bool StarSystem::CanBeHost()
{
	return true;
}

/*--------------------------------------------------------------------------*/

void StarSystem::ProcessInitData(void* data)
{
	StarSystemDesc* ssd = (StarSystemDesc*) data;

	if (ssd)
	{
		this->m_desc = *ssd;
	}
}

/*--------------------------------------------------------------------------*/

CameraDesc StarSystem::GetChildCameraDesc()
{
	CameraDesc cd;
	cd.m_farplane = 1000000000.0f;
	cd.m_nearplane = 1.0f;
	cd.m_fov = 70.0f;
	cd.m_method = ERenderPhaseMethod::DeferredShading;

	return cd;
}

/*--------------------------------------------------------------------------*/

void StarSystem::OnEnter()
{
	this->m_isCamInside = true;
}

/*--------------------------------------------------------------------------*/

void StarSystem::OnLeave()
{
	this->m_isCamInside = false;
}

/*--------------------------------------------------------------------------*/

void StarSystem::OnPreCalc()
{
	if (this->m_isCamInside)
	{
		glm::vec3 campos = this->GetSceneInstance()->GetCamera()->GetPosition();

		if (glm::distance(campos, glm::vec3()) > this->GetRadius())
		{
			g_Explorer->Pop(glm::vec3());
		}
	}
}

/*--------------------------------------------------------------------------*/
